home *** CD-ROM | disk | FTP | other *** search
/ Ham Radio 2000 #1 / Ham Radio 2000.iso / ham2000 / packet / terminal / gp161b / gpri.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1993-09-28  |  11.7 KB  |  406 lines

  1. {$A+,B-,D-,E-,F+,G-,I-,L-,N-,O-,R-,S-,V+,X+}
  2.  
  3. UNIT GPRI;
  4.  
  5. { Unit zum Erstellen von GPRI-Programmen für GP in Turbo Pascal ((C) Borland International Inc.) }
  6. { Erstellt von Ulf Saran, DH1DAE 1992, letzte Änderung 28.09.1993                                }
  7. { Es wird mindestens Version 6.0 benötigt, Borland Pascal 7.0 wurde noch nicht getestet          }
  8. { Diese Unit darf nach eigenen Wünschen verändert werden, sofern die Änderungen im Sourcecode    }
  9. { durch Kommentare deutlich gemacht werden.                                                      }
  10.  
  11.  
  12. Interface
  13.  
  14. TYPE
  15.   Str80 = String[80];
  16.  
  17.   TaskType = RECORD        { Datenstruktur zur Übergabe der Sprungadressen }
  18.     PrefixSegment :  Word; { Präfix-Segment des Remote-Programms           }
  19.     InitPtr,               { Zeiger auf die Init-Routine                   }
  20.     RXPtr,                 { Zeiger auf die Empfangs-Routine               }
  21.     StrategiePtr,          { Zeiger auf die Strategie-Routine              }
  22.     ExitPtr :  Pointer;    { Zeiger auf die Exit-Routine                   }
  23.   END;
  24.  
  25.   QSODataType = RECORD     { Datenstruktur zur Ermittlung der QSO-Daten    }
  26.                   MyCall,
  27.                   Call     :  String[9];
  28.                   Name     :  Str80;
  29.                   Pfad     :  String;
  30.                 END;
  31.  
  32.  
  33.  
  34. FUNCTION TaskInit (InitPr,RXPr,StrategiePr,ExitPr : Pointer) : Boolean;
  35. FUNCTION InstallTXHandler (TXPr : Pointer) : Boolean;
  36. FUNCTION InstallGPRIMessageHandler (GPRIMPr : Pointer) : Boolean;
  37. FUNCTION Send (S : String; Mode : Byte; Macro : Boolean) : Boolean;
  38. PROCEDURE SendString (S : String);
  39. PROCEDURE SendMacroString (S : String);
  40. FUNCTION StartFileTransfer (Mode : Byte; FName : Str80) : Boolean;
  41. PROCEDURE SendGPRIMessage (Ident : Word; VAR Data);
  42. PROCEDURE DisconnectChannel;
  43. PROCEDURE GetQSOData (VAR QSO : QSODataType);
  44.  
  45.  
  46. CONST
  47.   { Konstanten für das Mode-Byte beim Senden eines Strings zu GP }
  48.   DefaultMode    = 0;    { Text aussenden, Echo ausgeben, Sendepuffer nicht sofort leeren }
  49.   Flush          = 1;    { Sendepuffer sofort leeren }
  50.   TXOnly         = 2;    { Text nur aussenden, aber kein Echo im RX-Fenster }
  51.   EchoOnly       = 4;    { Text nur im RX-Fenster anzeigen, jedoch nicht aussenden }
  52.  
  53.                          { Ein Echo wird generell nur angezeigt, wenn es bei GP eingeschaltet ist }
  54.  
  55.   Macro          = TRUE;
  56.   NoMacro        = FALSE;
  57.  
  58.  
  59.   GPRI_VersionHi : Byte = 1;
  60.   GPRI_VersionLo : Byte = 0;
  61.   ProgrammEnde   : Boolean = FALSE; { Programmende-Flag.  }
  62.                                     { TRUE :  GP soll Programm beenden }
  63.                                     { FALSE :  Programm soll weiterlaufen }
  64.  
  65. VAR
  66.   InitPointer,
  67.   StrategiePointer,
  68.   ExitPointer,
  69.   GPRIMessagePointer,
  70.   TXPointer,
  71.   RXPointer        :  Pointer;
  72.   Handle           :  Byte;    { Handle-Nummer des GPRI-Programms }
  73.  
  74.  
  75. Implementation 
  76.  
  77.  
  78. VAR
  79.   TaskData   : TaskType;
  80.   SendPtr,              { Pointer auf Sende-Routine von GP }
  81.   GetDataPtr,           { Pointer auf die QSO_Daten-Routine von GP }
  82.   GPRIMessagePtr,       { Pointer auf die GPRI-Message-Routine von GP }
  83.   DisconPtr,            { Pointer auf die Disconnect-Routine von GP }
  84.   FTransfPtr : Pointer; { Pointer auf die Filetransfer-Routine von GP }
  85.  
  86.  
  87.  
  88.  
  89. PROCEDURE InitProc; Assembler; { Initialisierungs-Procedure, wird nur }
  90.                                { einmal beim Programmstart aufgerufen }
  91. ASM
  92.   MOV AX,SEG @DATA { Datensegment umschalten }
  93.   MOV DS,AX
  94.   CALL InitPointer { User-Routine aufrufen }
  95.   MOV BL,ProgrammEnde { Programmende-Flag an GP übergeben }
  96. END;
  97.  
  98.  
  99.  
  100. PROCEDURE RXProc; Assembler; { Empfangs-Procedure.  Wird von GP }
  101.                              { aufgerufen, wenn Daten empfangen wurden }
  102. ASM
  103.   MOV AX,SEG @DATA { Datensegment umschalten }
  104.   MOV DS,AX
  105.   PUSH ES { Umwandlung des Zeigers ES:DX in eine TP- }
  106.   PUSH DX { Stringübergabe.  ES:BX -> Empfangsdaten }
  107.   CALL RXPointer { User-Routine aufrufen }
  108.   MOV BL,ProgrammEnde { Programmende-Flag an GP übergeben }
  109. END;
  110.  
  111.  
  112.  
  113. PROCEDURE TXProc; Assembler;     { Sende-Procedure.  Wird von GP aufgerufen,  }
  114.                                  { wenn Daten auf der Tastatur eingegeben und }
  115.                                  { gesendet werden sollen.                    }
  116. ASM
  117.   MOV AX,SEG @DATA { Datensegment umschalten }
  118.   MOV DS,AX
  119.   PUSH ES { Umwandlung des Zeigers ES:DX in eine TP- }
  120.   PUSH DX { Stringübergabe.  ES:BX -> Sendedaten }
  121.   CALL TXPointer   { User-Routine aufrufen }
  122.   MOV BL,ProgrammEnde { Programmende-Flag an GP übergeben }
  123. END;
  124.  
  125.  
  126.  
  127. PROCEDURE StrategieProc; Assembler; { "Strategie-Routine".  Wird von GP }
  128.                                     { periodisch aufgerufen }
  129. ASM
  130.   MOV AX,SEG @DATA { Datensegment umschalten }
  131.   MOV DS,AX
  132.   CALL StrategiePointer { User-Routine aufrufen }
  133.   MOV BL,ProgrammEnde { Programmende-Flag an GP übergeben }
  134. END;
  135.  
  136.  
  137. PROCEDURE ExitProc; Assembler; { Exit-Routine.  Wird von GP vor der }
  138.                                { Beendigung des Programms aufgerufen }
  139. ASM
  140.   MOV AX,SEG @DATA { Datensegment umschalten }
  141.   MOV DS,AX
  142.   CALL ExitPointer { User-Routine aufrufen }
  143. END;
  144.  
  145.  
  146.  
  147. PROCEDURE GetGPRIMessage; Assembler;
  148.  
  149. ASM
  150.   MOV  AX,SEG @DATA
  151.   MOV  DS,AX
  152.   PUSH CX
  153.   PUSH ES
  154.   PUSH DX
  155.   CALL GPRIMessagePointer
  156. END;
  157.  
  158.  
  159.  
  160. FUNCTION Send (S : String; Mode : Byte; Macro : Boolean) : Boolean; Assembler;
  161. { Sendet einen String zu GP }
  162.  
  163. ASM
  164.   LES DX,S      { Zeiger ES:DX auf String S erzeugen }
  165.   MOV BX,DX
  166.   MOV BH,Mode   { Sende-Modus }
  167.   MOV BL,Handle { Handle-Nummer ins BL-Register }
  168.   MOV CL,Macro  { Macro-Flag }
  169.   CALL SendPtr  { GP-Routine aufrufen }
  170. END;
  171.  
  172.  
  173.  
  174. PROCEDURE SendString (S : String);
  175. { Sendet einen String auf dem connecteten Kanal aus (ohne Makroauswertung) }
  176.  
  177. VAR
  178.   Mode   : Byte;
  179.  
  180. BEGIN
  181.   IF S[0] = #0 THEN Exit;   { Wenn Leerstring, dann Routine sofort beenden }
  182.   IF S[Byte(S[0])] = #13 THEN
  183.     Mode := 0
  184.   ELSE
  185.     Mode := Flush;
  186.   Send(S,Mode,NoMacro);
  187. END;
  188.  
  189.  
  190.  
  191.  
  192. PROCEDURE SendMacroString (S :  String);
  193. { Sendet einen String auf dem connecteten Kanal aus (mit Makroauswertung) }
  194.  
  195. VAR
  196.   Mode   : Byte;
  197.  
  198. BEGIN
  199.   IF S[0] = #0 THEN Exit;   { Wenn Leerstring, dann Routine sofort beenden }
  200.   IF S[Byte(S[0])] = #13 THEN
  201.     Mode := 0
  202.   ELSE
  203.     Mode := Flush;
  204.   Send(S,Mode,Macro);
  205. END;
  206.  
  207.  
  208.  
  209.  
  210. FUNCTION StartFileTransfer (Mode :  Byte; FName :  Str80) : Boolean; Assembler;
  211. { Startet einen Filetransfer auf dem connecteten Kanal. }
  212. { FName :  Dateiname (kompletter Pfad)                  }
  213. { Mode  :  0 = Textdatei                                }
  214. {          1 = Binärmodus (kein AutoBin)                }
  215. {          2 = AutoBin-Modus                            }
  216.  
  217. ASM
  218.   LES DX,FName    { Zeiger ES:DX auf String FName erzeugen }
  219.   MOV BL,Handle   { Handlenummer ins BL-Register }
  220.   MOV BH,Mode     { Modusnummer ins BH-Register }
  221.   CALL FTransfPtr { GP-Routine aufrufen }
  222. END;
  223.  
  224.  
  225.  
  226. PROCEDURE SendGPRIMessage (Ident : Word; VAR Data); Assembler;
  227. { Sendet eine Nachricht an andere GPRI-Programme }
  228. { Ident : Identifikationsnummer                  }
  229. { Data  : Datenstruktur (beliebig)               }
  230.  
  231. ASM
  232.   PUSH DS
  233.   LES  DX,Data
  234.   MOV  BL,Handle
  235.   MOV  CX,Ident
  236.   CALL GPRIMessagePtr
  237.   POP  DS
  238. END;
  239.  
  240.  
  241.  
  242.  
  243. PROCEDURE DisconnectChannel; Assembler;
  244. { Disconnected den Kanal, das GPRI-Programm wird dabei automatisch }
  245. { beendet.                                                         }
  246.  
  247. ASM
  248.   MOV  BL,Handle
  249.   CALL DisconPtr { GP-Routine aufrufen }
  250. END;
  251.  
  252.  
  253.  
  254. PROCEDURE GetQSOData (VAR QSO :  QSODataType); Assembler;
  255. { Liefert verschiedene Daten über das QSO zurück                          }
  256. { Die Datenstruktur ist im Variablentyp "QSODataType" festgelegt und darf }
  257. { nicht geändert werden.                                                  }
  258.  
  259. ASM
  260.   LES DX,QSO      { Zeiger ES:DX auf Variable QSO erzeugen }
  261.   MOV BL,Handle   { Handle-Nummer ins BL-Register }
  262.   CALL GetDataPtr { GP-Routine aufrufen }
  263. END;
  264.  
  265.  
  266.  
  267. FUNCTION InstallTXHandler (TXPr : Pointer) : Boolean;
  268.  
  269. VAR
  270.   TXPtr    : Pointer;
  271.  
  272. BEGIN
  273.   IF TXPr <> NIL THEN BEGIN
  274.     TXPointer := TXPr;
  275.     TXPtr := @TXProc;
  276.     ASM
  277.       MOV  AX,$DF04        { Set TX entry point }
  278.       LES  BX,TXPtr
  279.       INT  $2F
  280.       CMP  AX,$4750
  281.       JNE  @Fehler
  282.       MOV  @Result,1
  283.       JMP  @Ende
  284.      @Fehler:
  285.       MOV  @Result,0
  286.      @Ende:
  287.     END;
  288.   END ELSE
  289.     InstallTXHandler := FALSE;
  290. END;
  291.  
  292.  
  293.  
  294. FUNCTION InstallGPRIMessageHandler (GPRIMPr : Pointer) : Boolean;
  295.  
  296. VAR
  297.   MessagePtr   : Pointer;
  298.  
  299. BEGIN
  300.   IF GPRIMPr <> NIL THEN BEGIN
  301.     GPRIMessagePointer := GPRIMPr;
  302.     MessagePtr := @GetGPRIMessage;
  303.     ASM
  304.       MOV  AX,$DF03        { Exchange GPRI Message Vectors }
  305.       LES  BX,MessagePtr
  306.       INT  $2F
  307.       CMP  AX,$4750
  308.       JNE  @Fehler
  309.       MOV  WORD PTR [GPRIMessagePtr+2],ES
  310.       MOV  WORD PTR [GPRIMessagePtr+0],BX
  311.       MOV  @Result,1
  312.       JMP  @Ende
  313.      @Fehler:
  314.       MOV  @Result,0
  315.      @Ende:
  316.     END;
  317.   END ELSE
  318.     InstallGPRIMessageHandler := FALSE;
  319. END;
  320.  
  321.  
  322.  
  323.  
  324. FUNCTION TaskInit (InitPr,RXPr,StrategiePr,ExitPr :  Pointer) :  Boolean;
  325. { Prüft, ob GPRI installiert ist und tauscht dann die Adressen der }
  326. { verschiedenen Routinen mit GP aus.                               }
  327. { Ausgabe:  TRUE = Programm erfolgreich installiert                }
  328. { FALSE = GPRI nicht installiert                                   }
  329.  
  330. BEGIN
  331.   RXPointer := RXPr;
  332.   InitPointer := InitPr;
  333.   StrategiePointer := StrategiePr;
  334.   ExitPointer := ExitPr;
  335.   WITH TaskData DO BEGIN
  336.     PrefixSegment := PrefixSeg;
  337.     IF InitPr <> NIL THEN InitPtr := @InitProc;
  338.     IF RXPr <> NIL THEN RXPtr := @RXProc;
  339.     IF StrategiePr <> NIL THEN StrategiePtr := @StrategieProc;
  340.     IF ExitPr <> NIL THEN ExitPtr := @ExitProc;
  341.   END;
  342.   ASM
  343.     MOV AX,$DFFF    { Get Version Number }
  344.     INT $2F
  345.     CMP AX,$4750    { Ist AX = 4750h? }
  346.     JNE @Fehler     { Wenn Nein -> Fehler }
  347.     MOV GPRI_VersionHi,BH
  348.     MOV GPRI_VersionLo,BL
  349.  
  350.     MOV AX,$DF02    { Get QSO Data Procedure Pointer }
  351.     INT $2F
  352.     MOV WORD PTR [GetDataPtr+2],ES
  353.     MOV WORD PTR [GetDataPtr],BX
  354.     CMP AX,$4750    { Ist AX = 4750h?  }
  355.     JNE @Fehler     { Wenn Nein -> Fehler }
  356.  
  357.     MOV AX,DS              { Datensegment ins ES-Register...              }
  358.     MOV ES,AX
  359.     MOV BX,OFFSET TaskData { ...und Offset ins BX-Register, fertig ist    }
  360.                            { der Zeiger ES:BX auf die Variable "TaskData" }
  361.     MOV AX,$DF00           { Register as Remote Program}
  362.     INT $2F                { Interrupt 2Fh aufrufen }
  363.     MOV WORD PTR [SendPtr+2],ES { Zeiger "SendPtr" mit ES:DX laden }
  364.     MOV WORD PTR [SendPtr],BX
  365.     MOV Handle,CL   { CL-Register in Variable "Handle" schreiben }
  366.     CMP AX,$4750    { Ist AX = 4750h? }
  367.     JNE @Fehler     { Wenn Nein -> Fehler }
  368.  
  369.     MOV AX,$DF01    { Get Filetransfer Procedure Pointer }
  370.     INT $2F { Interrupt 2Fh aufrufen }
  371.     MOV WORD PTR [FTransfPtr+2],ES { Zeiger "FTransfPtr" mit ES:BX laden }
  372.     MOV WORD PTR [FTransfPtr],BX
  373.     CMP AX,$4750                   { Ist AX = 4750h?  }
  374.     JNE @Fehler     { Wenn Nein -> Fehler }
  375.  
  376.     MOV AX,$DF05    { Get Disconnect Procedure Pointer }
  377.     INT $2F { Interrupt 2Fh aufrufen }
  378.     MOV WORD PTR [DisconPtr+2],ES  { Zeiger "FTransfPtr" mit ES:BX laden }
  379.     MOV WORD PTR [DisconPtr],BX
  380.     CMP AX,$4750                   { Ist AX = 4750h?  }
  381.     JNE @Fehler     { Wenn Nein -> Fehler }
  382.  
  383.     MOV @Result,1   { "TRUE" zurückliefern }
  384.     JMP @Ende       { und ans Ende springen }
  385.  
  386.    @Fehler:
  387.     MOV @Result,0   { "FALSE" zurückliefern }
  388.  
  389.    @Ende:
  390.   END;
  391. END;
  392.  
  393.  
  394.  
  395. BEGIN { Inititalisierung der Variablen }
  396.   Handle := 0;
  397.   WITH TaskData DO BEGIN
  398.     PrefixSegment := 0;
  399.     InitPtr := NIL;
  400.     RXPtr := NIL;
  401.     StrategiePtr := NIL;
  402.     ExitPtr := NIL;
  403.   END;
  404. END.
  405.  
  406.